#include "../thirdparty/Simple-Web-Server/client_http.hpp"
#include "../thirdparty/Simple-Web-Server/server_http.hpp"
#include <thread>
#include <chrono>
#include <filesystem>

#include <opencv2/opencv.hpp>


#include <fstream>

#ifdef HAVE_OPENSSL
#include "crypto.hpp"
#endif

#include "spdlog/spdlog.h"
#include "lib/webserver/web_server.h"
#include "lib/service/ai_service.h"
#include "lib/controller/ai_controller.h"
#include "lib/data/data_store.h"
#include "lib/base/system_config.h"

using namespace ai::facial_recognition;
using namespace std;
namespace fs = std::filesystem;

static volatile sig_atomic_t run = 1;

static void sigterm(int sig)
{
    std::cout << "Signal received: " + std::to_string(sig) << std::endl;
    run = 0;
}

int main()
{

    // 检查配置文件
    auto const config_filename = "config.ini";
    std::ifstream file(config_filename);
    if (!file)
    {
        std::cout << "配置文件" << config_filename << "不存在，请检查！" << std::endl;
        return -1;
    }

    SystemConfig system_config;
    

    spdlog::set_level(spdlog::level::debug); // Set global log level to debug
    spdlog::info("Application is starting......");

    signal(SIGINT, sigterm);
    signal(SIGTERM, sigterm);

    AIController ai_controller;

    // Initialize web server with port 8080
    WebServer web_server{8080};
    // 初始化服务
    AIService ai_service{};

    auto db_uri = system_config.readKey<std::string>("db", "db_uri", "face.db");
    spdlog::info("db_uri: {}", db_uri);
    DataStore data_store{db_uri};

    ai_service.set_data_store(&data_store);
    web_server.set_data_store(&data_store);

    web_server.subscribeRequest([&](RequestMessagePtr msg)
                                { ai_controller.onWebRequest(msg); });
    ai_controller.subscribeRequest([&](RequestMessagePtr msg)
                                   { ai_service.onWebRequest(msg); });

    spdlog::info("Demo(web_server) is starting......");
    ai_service.start();
    web_server.start();

    ai_service.connect_rtsp();

    spdlog::info("Demo has started.");

    while (run)
    {
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }

    spdlog::info("Demo is terminating......");

    ai_service.disconnect_rtsp();

    spdlog::info("Rtsp disconnected.");

    web_server.stop();
    ai_service.stop();

    spdlog::info("Web_server stopped.");
    spdlog::info("Application terminated.");
}
